<?php

namespace App\Models;

use App\Jobs\LotteryDraw;
use App\Models\Common\Common;
use App\Models\Tools\AliOss;
use App\Models\Tools\Data;
use App\Models\Tools\Message;
use App\Models\Tools\Period;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class Activity
{

    /**
     * 随机抽奖码(每个店铺的抽奖码永远不可以重复，最高900000个抽奖码)
     * @param int $shop_id 活动ids
     * @return bool|int
     */
    public static function getCode($shop_id)
    {
        // 查询这个店铺所有的活动id
        $act_ids = DB::table('lottery_activity')->where('shop_id','=',$shop_id)->pluck('act_id')->toArray();
        $times = 0;
        // 最大尝试次数100次
        while ($times < 100) {
            // 尝试次数+1
            $times++;
            // 随机一个数，查询是否存在
            $code = mt_rand(100000, 999999);
            $result = DB::table('lottery_users_draw')->where('code','=',$code)->whereIn('act_id',$act_ids)->count();
            // 如果已存在，重新循环
            if ($result > 0) continue;
            return $code;
        }
        return false;
    }

    /**
     * 查询活动信息（简单查单表）
     * @param $act_id
     * @return mixed
     */
    public static function activityMessage($act_id)
    {
        $activity = DB::table('lottery_activity as la')->where('act_id', '=', $act_id)->first();
        $activity = json_decode(json_encode($activity), true);
        $activity['status_name'] = Data::$lotteryActivityStatus[$activity['status']];
        $activity['overtime'] = (strtotime($activity['draw_time']) < Activity::overTime()) && ($activity['status'] === Data::DATA_DB_LOTTERY_ACTIVITY_STATUS_AFTER);
        if ($activity['cancel_user']) {
            $activity['cancel_user_name'] = DB::table('users')->where('id', '=', $activity['cancel_user'])->value('name');
        }
        return $activity;
    }

    /**
     * 中奖信息
     * @param $act_id
     * @return mixed|null
     */
    public static function winnerMessage($act_id)
    {
        $winner = DB::table('lottery_draw_detail as ldd')
            ->leftJoin('talent', 'ldd.we_id', '=', 'talent.we_id')
            ->leftJoin('explore_channel as ec', 'talent.channel_id', '=', 'ec.channel_id')
            ->leftJoin('users as u1', 'ldd.consumed_by', '=', 'u1.id')
            ->where('ldd.act_id', '=', $act_id)
            ->select('ldd.win_id', 'ldd.consumed', 'ldd.consumed_at','ldd.buy_img',
                'talent.talent_id', 'ec.channel_name', 'talent.account_name', 'u1.name as consumed_user')
            ->get()
            ->toArray();
        $winner = json_decode(json_encode($winner), true);
        $winner = $winner[0] ?? null;
        $winner['buy_img'] = AliOss::getUrl($winner['buy_img']);
        return $winner;
    }

    /**
     * 查询活动的所有参与记录
     * @param $act_id
     * @return mixed
     */
    public static function participateMessage($act_id)
    {
        $result = DB::table('lottery_users_draw as lud')
            ->leftJoin('talent', 'lud.we_id', '=', 'talent.we_id')
            ->leftJoin('explore_channel as ec', 'talent.channel_id', '=', 'ec.channel_id')
            ->where('lud.act_id', '=', $act_id)
            ->select('lud.participate_id', 'lud.code', 'lud.created_at', 'talent.we_id', 'talent.talent_id', 'talent.channel_id', 'talent.account_name', 'ec.channel_name')
            ->get()
            ->toArray();
        return json_decode(json_encode($result), true);
    }

    /**
     * 可核销的draw_time时间节点
     * 生产：14天，
     * 测试：1小时
     * @return int
     */
    public static function overTime()
    {
        return (env('APP_ENV') === 'production') ? now()->addDays(-14)->timestamp : now()->addHour()->timestamp;
    }

    /**
     * 关闭抽奖
     * @param array $activity 抽奖信息
     * @param string $remark 关闭原因
     * @return bool
     */
    public static function drawCancel($activity, $remark)
    {
        // 修改活动状态
        DB::table('lottery_activity')->where('act_id', '=', $activity['act_id'])->update([
            'status' => Data::DATA_DB_LOTTERY_ACTIVITY_STATUS_CANCEL,
            'canceled_at' => date('Y-m-d H:i:s'),
            'remark' => $remark,
        ]);
        $shop_type = DB::table('shop')->where('shop_id','=',$activity['shop_id'])->value('shop_type');
        // 直接返回商家活动次数余额
        $remaining = DB::table('lottery_remaining')
            ->where('we_id', '=', $activity['creator'])
            ->where('st_id','=',$shop_type)
            ->first();
        $remaining = json_decode(json_encode($remaining), true);
        if ($remaining['in_use_times'] < 1) {
            Log::emergency('霸王餐活动开奖：无人参与，退回余额时商家剩余次数异常', ['activity' => $activity, 'remaining' => $remaining]);
            return false;
        }
        DB::table('lottery_remaining')->where('we_id', '=', $activity['creator'])->where('st_id','=',$shop_type)->increment('remaining_times');
        DB::table('lottery_remaining')->where('we_id', '=', $activity['creator'])->where('st_id','=',$shop_type)->decrement('in_use_times');
        Log::debug('霸王餐活动开奖：无人中奖', ['activity' => $activity, 'remark' => $remark]);

        // 发送无人中奖通知给店主

        // 查询商品信息
        $goods_message = DB::table('lottery_goods')->where('goods_id', '=', $activity['goods_id'])->first();
        $goods_message = json_decode(json_encode($goods_message), true);
        $data = [
            'first' => '您发布的霸王餐无人中奖。',
            'keyword1' => $goods_message['goods_name'],
            'keyword2' => $goods_message['price'],
            'keyword3' => '-',
            'keyword4' => date('Y-m-d H:i:s'),
            'remark' => [
                'value' => '使用次数已退回原账户账户余额，请重新发单。',
                'color' => '#F00'
            ],
        ];
        $openid = DB::table('lottery_users')->where('we_id', '=', $activity['creator'])->value('openid');
        Common::sendLaifeiMessage($openid, 'open', $data, '/history');

        return true;
    }

    /**
     * 随机查找一个待中奖人
     * @param $act_id
     * @return mixed
     */
    public static function findParticipate($act_id)
    {
        // 检查是否还有可开奖的达人，随机查出一个
        $participates = DB::table('lottery_users_draw')
            ->where('act_id', '=', $act_id)
            ->where('status', '=', Data::DATA_DB_LOTTERY_USERS_DRAW_STATUS_BEFORE)
            ->inRandomOrder()
            ->first();
        $participates = json_decode(json_encode($participates), true);
        return $participates;
    }

    /**
     * 发送中奖参与通知
     * @param array $activity
     * @param array $participates
     */
    public static function sendConfirmMessage($activity, $participates)
    {
        $user = DB::table('lottery_users')->where('we_id', '=', $participates['we_id'])->first();
        $user = json_decode(json_encode($user), true);
        $goods_name = DB::table('lottery_goods')->where('goods_id', '=', $activity['goods_id'])->value('goods_name');

        // 发送短信通知
        Message::lotteryWin($user['phone'],$goods_name);


        // 发送模板信息
        try {

            $data = [
                'first' => '🍔🍔 您有霸王餐奖品待领取，限3小时，过期失效！',
                'keyword1' => '霸王餐',
                'keyword2' => $goods_name,
                'keyword3' => [
                    'value' => '👉点击领取',
                    'color' => '#0000FF'
                ],
                'keyword4' => date('Y-m-d H:i:s', time() + Period::getSetting('LOTTERY_NEXT_MEMBER')),
                'remark' => '
❌ 收到本消息不代表已经领取到霸王餐奖品

⭕ 请尽快进入订单领取奖品

⭕ 如领取超时，您的中奖机会将自动流转给其他参与者',
            ];

            Common::sendLaifeiMessage($user['openid'], 'win', $data, '/lottery/confirm?act_id=' . $activity['act_id']);

        } catch (\Exception $e) {
            Log::error(LotteryDraw::class . '发送微信通知失败', []);
        }
    }

    /**
     * 查询用户曾经赢得过的奖品id
     * @param int $we_id
     * @return array goods_ids
     */
    public static function winedGoodsIds($we_id)
    {
        return DB::table('lottery_draw_detail as ldd')
            ->leftJoin('lottery_activity as la', 'ldd.act_id', '=', 'la.act_id')
            ->where('we_id', '=', $we_id)
            ->pluck('la.goods_id')
            ->toArray();
    }


    /**
     * 查询用户曾经中奖过的店铺id
     * @param int $we_id
     * @return array shop_ids
     */
    public static function winedShopIds($we_id)
    {
        return DB::table('lottery_draw_detail as ldd')
            ->leftJoin('lottery_activity as la','ldd.act_id','=','la.act_id')
            ->where('we_id','=',$we_id)
            ->distinct('shop_id')
            ->pluck('shop_id')
            ->toArray();
    }

    /**
     * 查询用户参与的未开奖的奖品id
     * @param int $we_id
     * @return array goods_ids
     */
    public static function participatingGoodsIds($we_id)
    {
        return DB::table('lottery_users_draw as lud')
            ->leftJoin('lottery_activity as la', 'lud.act_id', '=', 'la.act_id')
            ->where('lud.we_id', $we_id)
            ->whereIn('lud.status', [
                Data::DATA_DB_LOTTERY_USERS_DRAW_STATUS_BEFORE,
                Data::DATA_DB_LOTTERY_USERS_DRAW_STATUS_WINING,
                Data::DATA_DB_LOTTERY_USERS_DRAW_STATUS_OVERTIME,
            ]) // 等待开奖和正在开奖的
            ->pluck('la.goods_id')
            ->toArray();
    }

    /**
     * 查询用户参与的未开奖的店铺id
     * @param int $we_id
     * @return array shop_id
     */
    public static function participatingShopIds($we_id)
    {
        return DB::table('lottery_users_draw as lud')
            ->leftJoin('lottery_activity as la','lud.act_id','=','la.act_id')
            ->where('lud.we_id','=',$we_id)
            ->whereIn('lud.status', [
                Data::DATA_DB_LOTTERY_USERS_DRAW_STATUS_BEFORE,
                Data::DATA_DB_LOTTERY_USERS_DRAW_STATUS_WINING,
                Data::DATA_DB_LOTTERY_USERS_DRAW_STATUS_OVERTIME, // 既超时
            ]) // 等待开奖和正在开奖的
            ->whereIn('la.status',[
                Data::DATA_DB_LOTTERY_ACTIVITY_STATUS_BEFORE,
                Data::DATA_DB_LOTTERY_ACTIVITY_STATUS_PRE, // 又正在参与
            ])
            ->distinct('shop_id')
            ->pluck('shop_id')
            ->toArray();
    }

    /**
     * 展示给达人的活动信息
     * @param int $activity_status 活动状态
     * @param null|int $participate_status 活动参与状态
     * @param bool $wined 是否中奖过此店铺的奖品
     * @param bool $pending 正在参与此店铺的其他抽奖
     * @return string[] 【permit】participate：参与抽奖,receive：领奖,use：使用
     */
    public static function activityStatus($activity_status, $participate_status = null, $wined = false, $pending = false)
    {
        $result = [
            'button' => '',
            'status' => '',
            'permit' => null,
            'type' => 'default',
        ];

        if ($wined && is_null($participate_status)) {
            $result['button'] = '您已中奖过此店铺的奖品';
            $result['status'] = '不可参与';
        } elseif ($pending && is_null($participate_status)) {
            $result['button'] = '您正在参与此店铺奖品的其他抽奖';
            $result['status'] = '不可参与';
        } else {
            switch ($activity_status) {
                case Data::DATA_DB_LOTTERY_ACTIVITY_STATUS_BEFORE: // 进行中
                    if (is_null($participate_status)) { // 参与
                        $result['button'] = '点击抽奖';
                        $result['status'] = '可参与';
                        $result['permit'] = 'participate';
                        $result['type'] = 'primary';
                    } else {
                        $result['button'] = '等待开奖';
                        $result['status'] = '等待开奖';
                        $result['type'] = 'warning';
                    }
                    break;
                case Data::DATA_DB_LOTTERY_ACTIVITY_STATUS_PRE:    // 正在开奖
                    if (is_null($participate_status)) {
                        $result['button'] = '未参与';
                        $result['status'] = '未参与';
                    } else {
                        switch ($participate_status) {
                            case Data::DATA_DB_LOTTERY_USERS_DRAW_STATUS_WINING: // 中奖领奖
                                $result['button'] = '点击领取';
                                $result['status'] = '已中奖';
                                $result['permit'] = 'receive';
                                $result['type'] = 'danger';
                                break;
                            case Data::DATA_DB_LOTTERY_USERS_DRAW_STATUS_BEFORE: // 其他人正在领奖
                                $result['button'] = '正在开奖';
                                $result['status'] = '正在开奖';
                                break;
                            case Data::DATA_DB_LOTTERY_USERS_DRAW_STATUS_OVERTIME: // 领奖超时
                                $result['button'] = '未领取';
                                $result['status'] = '未领取';
                                break;
                        }
                    }
                    break;
                case Data::DATA_DB_LOTTERY_ACTIVITY_STATUS_AFTER:  // 已开奖
                    if (is_null($participate_status)) {
                        $result['button'] = '未参与';
                        $result['status'] = '未参与';
                    } else {
                        if ($participate_status === Data::DATA_DB_LOTTERY_USERS_DRAW_STATUS_WIN) { // 中奖
                            $result['button'] = '已领取，查看使用方法';
                            $result['status'] = '已领取';
                            $result['permit'] = 'use';
                            $result['type'] = 'success';
                        } else { //未中奖
                            $result['button'] = '未中奖';
                            $result['status'] = '未中奖';
                        }
                    }
                    break;
                case Data::DATA_DB_LOTTERY_ACTIVITY_STATUS_SUCCESS: // 已结束
                    if (is_null($participate_status)) {
                        $result['button'] = '未参与';
                        $result['status'] = '未参与';
                    } else {
                        if ($participate_status === Data::DATA_DB_LOTTERY_USERS_DRAW_STATUS_WIN) { // 中奖
                            $result['button'] = '已使用';
                            $result['status'] = '已使用';
                        } else { //未中奖
                            $result['button'] = '未中奖';
                            $result['status'] = '未中奖';
                        }
                    }
                    break;
                case Data::DATA_DB_LOTTERY_ACTIVITY_STATUS_CANCEL:  // 已关闭
                    $result['button'] = '已关闭';
                    $result['status'] = '已关闭';
                    break;
            }
        }

        return $result;

    }

    public static function drawTime($end_time)
    {
        $hour = date('H', strtotime($end_time));
        if ((int)$hour < 8) {
            // 0-8点开奖，延时到8点
            $end_date = date('Y-m-d', strtotime($end_time));
            $end_time = $end_date . ' 08:00:00';
        }
        if ((int)$hour > 21) {
            // 21点以后，延时到第二天8点
            $end_date = date('Y-m-d', strtotime($end_time) + 24 * 60 * 60);
            $end_time = $end_date . ' 08:00:00';
        }
        return Carbon::make($end_time);
    }

}
